package cycling.taxi.com.base;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;

import cycling.taxi.com.R;
import cycling.taxi.com.manager.ThreadManager;
import cycling.taxi.com.utils.UiUtil;

/**
 * 控制器
 * Created by sixsix on 16/8/25.
 */
public abstract class LoadDataUi extends FrameLayout{
    //声明静态的常量状态值
    public static final int STATE_NONE = 0;
    public static final int STATE_LOADING = 1;
    public static final int STATE_ERROR = 2;
    public static final int STATE_EMPTY = 3;
    public static final int STATE_SUCCESS = 4;

    private  int mCurrentState = STATE_NONE;
    private View mLoadingView;
    private View mErrorView;
    private View mEmptyView;
    private View mSuccessView;


    public LoadDataUi(Context context) {
        super(context);
        initView();
    }

    public LoadDataUi(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        mLoadingView = View.inflate(UiUtil.getContext(), R.layout.pager_loading,null);
        addView(mLoadingView);

        mErrorView = View.inflate(UiUtil.getContext(), R.layout.pager_error,null);
        addView(mErrorView);

        mEmptyView = View.inflate(UiUtil.getContext(), R.layout.pager_empty,null);
        addView(mEmptyView);

        refreshUi();
}

    /**
     * 根据状态改变view的可见性
     */
    private void refreshUi() {

        mLoadingView.setVisibility(mCurrentState == STATE_LOADING?VISIBLE:GONE);
        mErrorView.setVisibility(mCurrentState == STATE_ERROR?VISIBLE:GONE);
        mEmptyView.setVisibility(mCurrentState == STATE_EMPTY?VISIBLE:GONE);


        //请求完成后，当状态为成功时
        if(mCurrentState == STATE_SUCCESS && mSuccessView == null){
            mSuccessView = getSuccessView();//抽象方法

            addView(mSuccessView);
        }
        if(mSuccessView!=null){
            //更新成功view的 状态
            mSuccessView.setVisibility(mCurrentState == STATE_SUCCESS?VISIBLE:GONE);
        }
    }

    protected abstract View getSuccessView();
    /**
     * 发起一个网络请求，在子线程中进行
     */
    public void loadData() {
        // 解决已经加载成功的页面，避免重复加载
        // 也就是说，如果上一次已经加载成功了，在此处做出拦截
        if(mCurrentState == STATE_SUCCESS ||mCurrentState == STATE_LOADING){
            return;
        }
        mCurrentState = STATE_LOADING;
        safeRefreshUi();//在开启子线程加载页面的时候，我们需要更新一次专业，把加载的效果画出来
       //new Thread( new LoadDataTask()).start(); //LoadDataTask是要在子线程做的任务
        // 这里可以使用线程池, 去获取普通的线程池，然后去执行，把LoadDataTask 加进去
        ThreadManager.getNormalPool().execute(new LoadDataTask());
    }

    private class LoadDataTask implements Runnable {
        @Override
        public void run() {
            // 不同到页面使用不同的网络访问组件，而现在还不知道会使用哪种，所以使用抽象方法。
            Result result =  getDataFromServer();
            mCurrentState = result.getState();
            //赋值之后就可以刷新ui了
            safeRefreshUi();
        }
    }

    /**
     * 抽取线程安全的刷新ui有2种
     * 1.activity.runOnUiThread
     * 2.使用handler
     */
    private  void safeRefreshUi(){
        UiUtil.postTask(new Runnable(){
            @Override
            public void run() {
                refreshUi();
            }
        });
    }

    /**
     * 关于枚举类的使用
     *  SUCCESS(STATE_SUCCESS),ERROR(STATE_ERROR),EMPTY(STATE_EMPTY);
     * 是利用构造函数传参，
     * 通过括号赋值,而且必须有带参构造器和属性和方法，否则编译出错，
     * 赋值必须是都赋值或都不赋值，不能一部分赋值一部分不赋值，
     * 如果不赋值则不能写构造器，赋值编译也出错，
    */
    public enum Result{
        SUCCESS(STATE_SUCCESS),ERROR(STATE_ERROR),EMPTY(STATE_EMPTY);

        private int state; //定义私有变量
        Result(int state){ //带参数的构造函数，枚举类型只能为私有
            this.state = state;
        }
        //提供get的方法，之后也要set方法，在合适的时间，把值传进去，这里用构造函数
        public int getState() {
            return state;
        }
    }

    /**
     * 从服务器获取数据
     * 这个方法的返回值是int类型的
     * 为了限制返回类型，这里将int改为枚举类型，
     * 故，定义一个枚举类 Result
     */
    protected abstract Result getDataFromServer();
}
